/*
 * Serum
 *
 * @license      GNU Lesser General Public Licence see LICENCE-LGPL file or http://www.gnu.org/licenses/lgpl.html
 */

Serum.Form.Module.Search = Ext.extend(Serum.Form.Module.Abstract, {

    /**
     * Constructor
     */
    constructor: function(config, selector, onSuccess) {
        this.elementId  = null;

        if (typeof selector === 'undefined') {
            selector = {};
        }

        this.module             = (typeof selector.module !== 'undefined')      ? selector.module       : Serum.Selector.get().module;
        this.controller         = (typeof selector.controller !== 'undefined')  ? selector.controller   : Serum.Selector.get().controller;
        this.action             = (typeof selector.action !== 'undefined')      ? selector.action       : Serum.Selector.get().action;
        this.parentRoot         = (typeof selector.parentRoot !== 'undefined')  ? selector.parentRoot   : Serum.Selector.get().getParams['parentRoot'];
        this.onSuccessHandler   = (typeof onSuccess === 'function')             ? onSuccess             : this.onSuccess;

        Serum.Form.Module.Edit.superclass.constructor.call(this, Ext.apply({
            labelWidth:     120,
            border:         false,

            autoScroll:     true,

            layout:         'form',
            bodyStyle:      'padding: 15px',

            defaultType:    'textfield',
            monitorValid:   true,
            items:          [],

            keys: [{
                key:    Ext.EventObject.ENTER,
                fn:     this.submitForm,
                scope:  this
            }],

            buttons: [{
                scope:      this,
                type:       'submit',
                text:       __('base~form_search'),

                handler: function() {
                    this.submitForm();
                }
            }]

        }, config));
    },

    /**
     * Returns form title
     *
     * @return  {String}
     */
    getTitle: function() {
        return __(this.module.toLowerCase() + '~form_search_title', 'base~form_search_title');
    },

    isFormAction: function() {
        return true;
    },

    /**
     * Preloads form items (delete former items)
     */
    preload: function(elementId) {
        this.elementId = null;

        if (typeof elementId !== 'undefined') {
            this.elementId = elementId;

        } else if (typeof Serum.Selector.get().getParams['id'] !== 'undefined' && this.isEditForm()) {
            this.elementId = Serum.Selector.get().getParams['id'];
        }

        if (typeof this.items !== 'undefined') {
            var i;
            while(i = this.items.last()) {
                this.remove(i, true);
            }
        }
    },

    /**
     * Loads form items
     */
    load: function(fieldsList) {
        this.build(fieldsList);
    },

    /**
     * Builds the form
     */
    build: function(fieldsList) {
        // Initializes request params
        var _params = {
                method: Serum.Selector.get().method({
                module: this.module,
                controller: this.controller
            }),
            requestId: Serum.Helper.Request.id()
        };

        if (typeof this.parentRoot !== 'undefined') {
            _params['parentRoot'] = this.parentRoot;

        } else if (typeof Serum.Selector.get().getParams['modelRoot'] !== 'undefined') {
            _params['modelRoot'] = Serum.Selector.get().getParams['modelRoot'];
        }

        // Ajax request to get fields list
        Serum.Ajax.request({
            scope:       this,
            params:      _params,
            onSuccess:  function(response) {
                            var jsonResponse = Ext.util.JSON.decode(response.responseText);

                            if (typeof jsonResponse['result']['fields'] !== 'undefined') {
                                this._build(jsonResponse['result'], fieldsList);
                            }
                        }
        });
    },

    /**
     * Requests server and processes returned errors
     */
    submitForm: function() {
        //this.onSuccess();

        this.form.submit({
            method:     'POST',
            url:        Serum.Selector.get().requestUrl('index'),
            params:     {
                method: Serum.Selector.get().method({
                    module:     this.module,
                    controller: this.controller,
                    action:     'search'
                })
            },
            waitTitle:  __('base~form_waitTitle'),
            waitMsg:    __('base~form_waitMsg'),

            success:    this.onSuccessHandler,
            failure:    this.onFailure,
            scope:      this
        });
    },

    /**
     * Called after a successful form submit.
     *
     * @param   {Ext.form.BasicForm}    form        Submitted form
     * @param   {Object}                action      Returned value
     */
    onSuccess: function(form, action) {
        var params          = {method: Serum.Selector.get().method({action: 'search'}),
                               search: {}};

        Ext.apply(params.search, action.result.params, {});

        Serum.App.get().eventListener.fireEvent('refreshlist', params);
    },

    /**
     * Called after a failed form submit.
     *
     * @param   {Ext.form.BasicForm}    form        Submitted form
     * @param   {Object}                action      Returned value
     */
    onFailure: function(form, action) {
        if (action['failureType'] == 'server') {
            var response    = Ext.util.JSON.decode(action['response']['responseText']);
            var errors      = response['errors'];

            if (typeof response['exception'] !== 'undefined') {
                Serum.Exception.Handler.process(response['exception']);
            }

            for(var error in errors) {
                var field = this.find('name', error)[0];

                if (typeof field !== 'undefined' && field instanceof Ext.form.Field) {
                    field.markInvalid(__(this.module.toLowerCase() + '~form_errors_' + errors[error], 'base~form_errors_' + errors[error]));
                }
            }

            this.items.first().focus();
        }
    },

    /**
     * Cleans fields errors
     */
    cleanErrors: function() {
        this.items.each(function(item) {
            if (typeof item.items !== 'undefined' && item.items instanceof Ext.util.MixedCollection) {
                item.items.each(function(field) {
                    if (field instanceof Ext.form.Field) {
                        field.clearInvalid();
                    }
                });
            }
        }, this);
    }
});